home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-02-10 | 40.7 KB | 2,198 lines |
-
-
-
- LENGUAJE C
-
- CONTROL DE DISQUETERAS
-
- Para mejorar la presentaci≤n de un programa es importante tener un
- control total de todos los errores que se puedan presentar. Una buena
- fuente de problemas son los accesos a las disqueteras. Por ejemplo,
- un problema muy clßsico es el intento de acceso a una disquetera sin
- disco, pues nos encontramos ante el clßsico mensaje de ½Anular,
- Repetir, Descartar?╗, algo poco deseable dentro de un programa.
- Avisar de todos los problemas que se puedan presentar es una buena
- forma de mejorar la calidad de un programa.
-
- Mediante la rutina biosdisk podemos saber el estado de la disquetera y
- asφ evitar los errores que acabamos de mencionar. Por ejmplo, antes
- de abrir un fichero de un disco, podemos ver si realmente estß el
- disco en la disquetera, y en caso afirmativo, abrirlo. Para comprobar
- el estado podemos utilizar el siguiente c≤digo:
-
- #include <bios.h>
-
- main() {
-
- int r, unidad = 0;
-
- char b[512];
-
- r=biosdisk(4,unidad,0,0,0,1,b);
-
- r=biosdisk(4,unidad,0,0,0,1,b);
-
- switch(r) {
-
- case 0x02: printf("Disco no formateado");break;
-
- case 0x08:
-
- case 0x09: printf("Fallo en el DMA");break;
-
- case 0x0C: printf("Tipo de disco no encontrado");break;
-
- case 0x10: printf("Error en el CRC");break;
-
- case 0x20: printf("Fallo en la controladora");break;
-
- case 0x40: printf("Fallo de b·squeda");break;
-
- case 0x80: printf("No hay disco en la disquetera");break;
-
- default : printf("Ok");break;
-
- }
-
- }
-
-
- La variable unidad vale 0 para A: y 1 para B:. Se llama dos veces
- seguidas a la funci≤n biosdisk, ya que la primera vez devuelve un valor
- que indica si se ha encontrado un disco, pero sin ver su estado.
-
- Ricard Forner Gili
-
- Barcelona
-
-
- SUPER PIXEL
-
- Este programa (realizado en ½Quick C╗ de Microsoft, aunque fßcilmente
- implementable en ½Turbo C╗) nos proporciona una nueva rutina para
- imprimir un pixel en una VGA 640x480. La nueva rutina estß realizada
- en ensamblador y proporciona una mayor velocidad que la instrucci≤n
- ½_setpixel╗. En este programa podemos comparar las dos instrucciones
- para ver la diferencia de velocidad de una a otra.
-
- #include <graph.h>
-
- void DP(int pagina,int i,int p,int color);
-
- main()
-
- {
- int x,y;char ca;
-
- _setvideomode(_VRES16COLOR);
-
- _clearscreen(_GCLEARSCREEN);
-
- printf("1.- Impresi≤n en 'C' (setpixel).\n");
-
- printf("2.- Impresi≤n 'ASSEMBLY' (dp).\n");
-
- while (ca!='1' && ca!='2') ca=getch();
-
- for (y=0;y<480;y=y+10)
-
- for (x=0;x<640;x=x+1)
-
- if (ca=='1') {_setcolor(1);_setpixel(x,y);}
-
- else DP(0,x,y,1);
-
- _setvideomode(_DEFAULTMODE);
-
- }
-
- void DP(int pagina,int t,int p,int color)
-
- {
-
- _asm{
-
- mov bh,[bp+6];
-
- mov cx,[bp+8];
-
- mov dx,[bp+10];
-
- mov al,[bp+12];
-
- mov ah,0Ch;
-
- int 10h;
-
- }
-
- }
-
- Juan Vercher Martφnez
-
- Gandφa (Valencia)
-
-
-
- INCLUYA 16 COLORES EN EL FONDO
-
- Este programa es un ejempo de c≤mo utilizar los colores comprendidos
- entre el 8 y el 15 como color de fondo. Hemos de recordar que para el
- color de fondo s≤lo podemos utilizar los colores del 0 al 7, de ahφ la
- motivaci≤n de este truco.
-
- La rutina ½parpadeo()╗ funciona por medio de la interrupci≤n 10h
- subservicio 03h, que permite activar o desactivar el atributo de
- parpadeo. La ROM BIOS utiliza el parpadeo por defecto, pero cambiando
- el valor del atributo se pueden utilizar los 16 colores para el fondo.
- El valor que se pasa en BL determina si el valor estß activado (01h) o
- desactivado (00h).
-
- Es necesario utilizar la funci≤n ½textattr()╗ (para definir los dos
- colores se puede emplear la f≤rmula ColorTexto+ColorFondo*16) para
- cambiar el color, ya que con las funciones ½textcolor()╗ y
- ½textbackground()╗ no es posible, puesto que reestablecen el atributo
- para parpadeo.
-
- #include <stdio.h>
-
- #include <dos.h>
-
- #include <conio.h>
-
- enum BOOLEAN {OFF, ON};
-
- void parpadeo (enum BOOLEAN activar);
-
- void parpadeo (enum BOOLEAN activar)
-
- {
-
- union REGS regs;
-
- regs.h.bl=activar ? 0x01 : 0x00;
-
- regs.h.ah=0x10;
-
- regs.h.al=0x03;
-
- int86(0x10,®s,®s);
-
- }
-
- void main()
-
- {
-
- int i,j;
-
- enum BOOLEAN parpadear;
-
- textattr( 0 + 15 * 16);
-
- cprintf("\n\rFONDO");
-
- for(i=1;i<16;i++) cprintf(" %2d ",i);
-
- for(i=0;i<16;i++)
-
- for (j=0;j<16;j++)
-
- {
-
- textattr(i+j*16);
-
- cprintf("Texto");
-
- }
-
- textattr(0+15*16);
-
- cprintf("Pulsa Esc para finalizar, otra tecla "
-
- "para cambiar el atributo de parpadeo...");
-
- parpadear = ON;
-
- while(i!=27)
-
- {
-
- parpadear=!parpadear;
-
- parpadeo(parpadear);
-
- i=getch();
-
- }
-
- parpadeo(ON);
-
- }
-
-
- Antonio Jes·s Ollero Sanguino
-
- Casar de Cßceres (Cßceres)
-
-
-
- TECLADOS VELOCES
-
- La ROM-BIOS permite obtener las teclas pulsadas a una velocidad mßxima
- de 30 caracteres por segundo y con un retardo de autorrepetici≤n de
- 0,25 segundos. Algunas veces interesa que el retardo de
- autorrepetici≤n sea menor y leer a mßs velocidad. Esta rutina
- soluciona este problema.
-
- #include <Dos.h>
-
- usigned char obt_tecla (void);
-
- {
-
- unsigned int *cabeza=(unsigned int *) (0x0000041a);
-
- unsigned int *cola=(unsigned int *) (0x0000041c);
-
- *cabeza=*cola
-
- return portb(0x60);
-
- }
-
- El funcionamiento de la rutina estß basado en la lectura del c≤digo de
- letra pulsada directamente del puerto, y ademßs se vacφa el buffer del
- teclado para que no se llene, ya que no se saca la tecla mediante
- ninguna llamada a la ROM-BIOS.
-
- Utilidad: Esta funci≤n puede ser de gran utilidad para juegos, en los
- cuales se requiere mover un grßfico o ejecutar una acci≤n seg·n la
- tecla pulsada. En estos casos suele resultar bastante lento tener que
- esperar los 0,25 segundos para que el ordenador detecte que se
- mantiene pulsada la misma tecla.
-
- Jorge Pastor Mondejar
-
- Molina de Segura (Murcia)
-
-
- SCROLL DE TEXTO
-
- Esta rutina realiza un scroll en pantalla mediante el uso de las
- interrupciones de la BIOS. La ventaja de esta tΘcnica radica en que
- permite la realizaci≤n un scroll en una ventana.
-
- Los parßmetros que se le pasan a la rutina son los siguientes:
-
- Fijo: atributo; este parßmetro representa el color.
-
- Fil: fila superior de la ventana donde se realiza el
- scroll.
-
- Col: columna mßs a la izquierda de la ventana donde se hace el
- scroll.
-
- Fils: fila inferior de la ventana donde se realiza el
- scroll.
-
- Col: columna mßs a la derecha de la ventana donde se hace el
- scroll.
-
- Atr: Funci≤n a realizar. Dependiendo de los parßmetros que le
- pasemos aquφ podrß realizar ½scroles╗ hacia arriba, abajo, etc, (es
- conveniente investigar).
-
- Numfils: n·mero de lφneas a mover.
-
- #include <bios.h>
-
- #include <stdio.h>
-
- #include <conio.h>
-
- union REGS inregs, outregs;
-
- void scroll (int fijo, int fil, int col, int fils, int cols, int atr,
- int numfils)
-
- {
-
- inregs.h.ah = atr;
-
- inregs.h.al = numfils;
-
- inregs.h.bh = fijo;
-
- inregs.h.ch = fil;
-
- inregs.h.cl = col;
-
- inregs.h.dh = fils;
-
- inregs.h.dl = cols;
-
- int86(0x10, &inregs, &outregs);
-
- }
-
- /* Programa de ejemplo */
-
- main()
-
- {
-
- int i,u;
-
- clrscr();
-
- for (i=0; i<30; i++)
-
- {
-
- gotoxy(50,3);
-
- printf("%d",i);
-
- scroll(7,2,49,19,60,7,1);
-
- getch();
-
- }
-
- }
-
- David G. Peris
-
- Barcelona
-
-
- SALIR AL DOS
-
- El objetivo de esta rutina es el de poder implementar un shell al DOS
- en los men·s de nuestros propios programas.
-
- Para realizar este cometido invocaremos una llamada al ½command.com╗
- mediante la orden ½SYSTEM╗, una vez que sepamos que el interprete de
- comandos estß en nuestro path activo. Si el ½command.com╗ no se
- encuentra en el path activo, sale de la funci≤n devolviendo 0, si no
- lo ejecuta y cuando se teclea ½EXIT╗ devuelve 1.
-
- Para saber si el ½command.com╗ estß a nuestra disposici≤n, utilizamos
- la sentencia ½SEARCHPATH╗ de la lφbreria <dir.h>. Si el ½command.com╗
- estß disponible devuelve la ruta completa de acceso a Θl; en caso
- contrario devuelve ½NULL╗.
-
- El programa ha sido compilado mediante ½Turbo C/C++ 1.0╗.
-
- #include <dir.h>
-
- #include <stdlib.h>
-
- #include <conio.h>
-
- int dos_shell();
-
- /* main de ejemplo */
-
- main ()
-
- {
-
- if dos_shell()==0)
-
- cprintf("\nNo se encontr≤ COMMAND COM en el path activo\n");
-
- return 0;
-
- }
-
- int dos_shell()
-
- {
-
- char *camino=NULL;
-
- camino =searchpath("COMMAND.COM");
-
- if (camino==NULL) return 0;
-
- clrscr();
-
- cprintf ("Teclea Exit para volver al programa. \n");
-
- system (camino);
-
- clrscr();
-
- return 1;
-
- }
-
- JosΘ Luis Moncada Collado
-
- Sant Adriß de Bes≤s (Barcelona)
-
-
-
- EFECTO OPTICO
-
- Este es un peque±o truco para lograr esos efectos ½visuales╗ que tanto
- suelen gustar a la gente. Consiste en un CLS muy llamativo, ya que
- todo lo que hay en la pantalla de texto desaparecerß como si de niebla
- o humo se tratase. Es ideal para programas en modo texto que no
- pueden acceder a los trucos que permite el modo grßfico.
-
- El programa accede directamente al buffer de vφdeo y ahφ va
- incrementando en uno todos los caracteres distintos de 0 (para evitar
- un bucle infinito) y todos los distintos de ½ ╗ (para no tocar el
- fondo, s≤lo el texto), asφ hasta que no quedan mßs que ceros o ½ ╗
- (espacio en blanco) entonces ya se habrß borrado la pantalla.
- Funciona tanto en color como en monocromo, y estß realizado con el
- Borland C++ 3.1 en ANSI C. Por lo que deberφa funcionar sin problemas
- en cualquier compilador de C que cumpla la norma ANSI.
-
- #include <stdio.h>;
-
- #include <dos.h>;
-
- #include <stdlib.h>;
-
- int modo_video(void),modov,humo(void);
-
- char far *mem_video;
-
- main()
-
- {
-
- modov=modo_video();
-
- if ((modov!=2) && (modov!=3) && (modov!=7)) {
-
- printf("\nEl modo de video debe estar en 80 columnas.");
-
- exit(1);
-
- }
-
- if (modov==7)
-
- mem_video = (char far *) 0xb0000000; /*Monocromo*/
-
- else
-
- mem_video = (char far *) 0xb8000000; /*Color */
-
- do{
-
- }while (humo()); /*Mientras humo devuelva un 1 es que hay caracteres*/
-
- printf("Prueba de desaparicion de caracteres realizada");
-
- return(0);
-
- }
-
- int modo_video(void)
-
- {
-
- union REGS r;
-
- r.h.ah=15; /*obtiene el modo de video */
-
- return int86(0x10,&r,&r) & 255;
-
- }
-
- int humo(void)
-
- {
-
- register char far *p;
-
- int bandera=0;
-
- for (p=mem_video;p<mem_video+80*25*2;p++,p++)
-
- if ((*p!=0) && (*p!=32)){
-
- (*p)++;
-
- bandera=1;
-
- }
-
- return(bandera);
-
- }
-
- Antonio Javier Garcφa Martφnez
-
- Granada
-
-
- GUARDAR Y RESTAURAR PANTALLAS
-
- Las siguientes rutinas realizadas en C++ son una mejora de las rutinas
- publicadas en el n·mero de febrero para guardar y restaurar pantallas
- de texto. Estos procedimientos muestran su utilidad cuando abrimos un
- men·, cuadro de dißlogo o ventana y al cerrarlo deseamos que
- reaparezca el contenido de la pantalla tal y como estaba
- anteriormente.
-
- La ventajas que ofrecen las nuevas rutinas es que trabajan
- directamente con la memoria de vφdeo. Para ello se basan en el
- principio de que los modos de texto de 80x25 disponen de cuatro
- pßginas de vφdeo que normalmente no se utilizan. Estos nuevos
- procedimientos -½SaveScreen (...)╗ y ½RestScreen(...)╗- copian las
- pantallas a otra pßgina, lo que permite que el acceso sea mßs rßpido.
-
- Tan s≤lo presentan una desventaja producida por la limitaci≤n de
- pßginas de vφdeo disponibles, pues en el modo 80x25 s≤lo disponemos de
- tres pßginas libres y en el modo 40x25 de siete pßginas. En cada
- pßgina libre podremos guardar una pantalla.
-
- El siguiente programa de ejemplo captura la pantalla de texto, despues
- espera a que se pulse una tecla, borra la pantalla y espera de nuevo
- otra pulsaci≤n de tecla, tras la cual restaura el contenido original
- de la pantalla.
-
- #include <stdio.h>
-
- #include <mem.h>
-
- void SaveScreen (unsigned short Pagina);
-
- void RestScreen (unsigned short Pagina);
-
- void main(void);
-
- {
-
- printf ("PC Actual");
-
- int c;
-
- SaveScreen (1);
-
- c=getchar();
-
- clrscr();
-
- c=getchar;
-
- RestScreen(1);
-
- }
-
-
- // Funciones Principales //
-
- void SaveScreen (unsigned short Pagina);
-
- {
- unsigned int Pos=Pagina*0x1000;
-
- movedata (0xB800, 0x0000, 0xB800, Pos, 4000);
-
- }
-
- void RestScreen (unsigned short Pagina);
-
- {
-
- unsigned int Pos=Pagina*0x1000;
-
- movedata (0xB800, Pos, 0xB800, 0x0000, 4000);
-
- }
-
-
- Daniel Sßnchez Teodoro
-
- Granada
-
-
- ESCALA DE GRISES
-
- Esta rutina realizada en Turbo C, aunque fßcilmente adaptable a Pascal
- o ensamblador, transforma la paleta de la pantalla MCGA o VGA 256
- colores (320 x 200 con 256 colores) a sus correspondientes valores de
- la escala de grises. En definitiva, cuando llamamos a esta funci≤n el
- grßfico de la pantalla se pone en blanco y negro, tal y como vemos en
- muchas mßquinas recreativas.
-
- Para transformar la paleta de la pantalla a grises ejecutaremos
- gris(0), mientras que para devolver a su estado original una paleta
- convertida a escala de grises escribiremos gris(1).
-
- Las dos rutinas para gris se pueden incluir en el m≤dulo principal del
- programa en C, pero en caso de que deseemos linkar esta funci≤n como
- un m≤dulo separado no hay que olvidar incluir el fichero ½.h╗ para
- acceder a ella.
-
- /* Funci≤n de transformaci≤n de grises
-
- #include <dos.h>
-
- #define GRIS 0
-
- #define COLOR 1
-
- void gris(void);
-
- static unsigned char paleta_antigua[256][3];
-
- static unsigned char activado;
-
- void gris (char modo)
-
- {
-
- switch(modo){
-
- case COLOR;
-
- if (!activado) break; /*sale si no hay grises */
-
- _ES = FP_SEG(paleta_antigua); /*Estas dos siempre primero */
-
- _DX = FP_OFF(paleta_antigua);
-
- _AX = 0x1012; /* Funci≤n BIOS para definir PALETA */
-
- _BX = 0;
-
- _CX = 256;
-
- geninterrupt (0x10); /* Llama a la BIOS */
-
- activado=~activado; /* Muta el indicador */
-
- break;
-
- case GRIS;
-
- if (activado) break; /*sale si ya hay grises */
-
- _ES = FP_SEG(paleta_antigua); /*Estas dos siempre primero */
-
- _DX = FP_OFF(paleta_antigua);
-
- _AX = 0x1017; /* Salva la paleta de color antigua */
-
- _BX = 0;
-
- _CX = 256;
-
- geninterrupt (0x10); /* Llama a la BIOS */
-
- _AX = 0x101B; /* Pasa a grises */
-
- _BX = 0;
-
- _CX = 256;
-
- geninterrupt (0x10); /* Llama a la BIOS */
-
- activado=~activado; /* Muta el indicador */
-
- break;
-
- }
-
- }
-
- Fichero ½gris.h╗:
-
- /* Cabecera del m≤dulo transformador de grises vφa BIOS (MCGA-VGA) */
-
- extern void gris(void);
-
- #define GRIS 0
-
- #define COLOR 1
-
- Luis Dφaz Villanueva
-
- Madrid
-
- Comentario del Laboratorio: La rutina se basa en la utilizaci≤n de la
- interrupci≤n 10 de la BIOS (encargada de los servicios de vφdeo),
- aunque mßs en concreto en la funci≤n 10, cuya misi≤n es la gesti≤n de
- los registros de la paleta de colores. La paleta de colores en el
- modo VGA 256 estß formada por 256 registros (uno por color) con tres
- valores cada uno (para la cantidad de rojo, verde y azul de cada
- color)
-
- Para llevar a cabo el truco se hace uso de la subfunci≤n 12, cuya
- misi≤n es la asignaci≤n de un bloque de registros de color; la
- subfunci≤n 17, que lee un bloque de registros de color, y, por ·ltimo,
- de la subfunci≤n 1B, que suma los valores de color para pasar a tonos
- de grises. Estas funciones necesitan tener cargado en ES la direcci≤n
- del segmento donde se encuentra la tabla donde leeremos o grabaremos
- los registros de color de la paleta. Ademßs, en DX debe cargarse el
- desplazamiento (offset) de dicha tabla.
-
- Para efectuar la llamada a la funci≤n cargamos el 10 (del n·mero de
- funci≤n) en el registro AH y el n·mero de subfunci≤n en el registro
- AL. Por ejemplo, cuando ejecutamos ½gris(0)╗ en el truco llamamos a
- la subfunci≤n 12, por eso en este caso cargamos en AH el 10 y en AL el
- 12, lo que es equivalente a cargar 1012 en AX. Una vez que hemos
- cargado el valor de la funci≤n a emplear debemos pasar en BX el n·mero
- de color desde el que queremos empezar a trabajar; en este caso nos
- interesa el primer color (el 0) para convertir toda la paleta.
- Ademßs, en CX cargaremos el n·mero de colores que queremos convertir.
- Por ·ltimo, modificando los valores de BX y CX conseguiremos tratar
- s≤lo un determinado rango de colores. Tras haber cargado todos los
- valores en cada uno de los registros se efect·a la llamada a la
- interrupci≤n 10.
-
-
- RUTINAS PARA LA PALETA
-
- Esta librerφa para C puede ser de gran utilidad para todos los
- programadores que utilicen cualquier modo grßfico y deseen ½jugar╗ con
- la paleta de colores.
-
- La funci≤n ½set_rgb╗ sirve para establecer los valores RGB, es decir,
- las cantidades de rojo, verde y azul (en este orden) que forman el
- color (½col╗). La funci≤n ½get_rgb╗ efect·a el proceso contrario, es
- decir, dado el color ½col╗ nos devuelve la cantidad de rojo, verde y
- azul que componen dicho color.
-
- TambiΘn podremos utilizar ½Make_gradiente╗ para crear una escala de
- gradientes. Como argumentos se le pasan los valores RGB (rojo, verde
- y azul) del color inicial y del color final, asφ como el color en que
- comienza la escala y el n·mero de colores que la compondrßn (si este
- ·ltimo argumento es negativo se pueden obtener escalas hacia atras).
-
- Por ·ltimo, la funci≤n ½ciclo╗ se utiliza para conseguir que una
- secci≤n de la paleta gire o rote sus colores. Se le pasan como
- argumentos el color inicial y final del segmento de paleta deseado.
- Con este efecto se consigue un resultado especialmente vistoso
- utilizßndolo en un bucle, logrando un efecto semejante al utilizado en
- algunos programas de fractales (como el Fractint).
-
- Un ejemplo de esto ·ltimo es:
-
- while (!kbhit())
-
- {
-
- ciclo(0,255);
-
- }
-
-
- La librerφa es la siguiente:
-
- #include <dos.h>
-
- typedef unsigned char byte;
-
- typedef struct
-
- {
-
- byte r;
-
- byte g;
-
- byte b;
-
- }rgb;
-
- void set_rgb (byte r, byte g, byte b, byte col);
-
- rgb get_rgb (byte col);
-
- void ciclo (byte inicio, byte fin);
-
- void make_gradiente (byte, byte, byte, byte, byte, byte, byte, int );
-
- void set_rgb (byte r, byte g, byte b, byte col)
-
- {
-
- outportb(0x3c8, col);
-
- outportb(0x3c9, r);
-
- outportb(0x3c9, g);
-
- outportb(0x3c9, b);
-
- }
-
- rgb get_rgb (byte col)
-
- {
-
- rgb result;
-
- outportb(0x3c7, col);
-
- result.r=inport(0x3c9);
-
- result.g=inport(0x3c9);
-
- result.b=inport(0x3c9);
-
- return (result);
-
- }
-
- void ciclo (byte inicio, byte fi)
-
- {
-
- int cont=0;
-
- rgb ci=get_rgb(inicio);
-
- rgb c;
-
- for (cont=inicio; cont <final; cont++)
-
- {
-
- c=get_rgb(cont+1);
-
- set_rgb(c.r, c.g, c.b, cont);
-
- }
-
- set_rgb(ci.r, ci.g, ci.b, final);
-
- }
-
- void make_gradiente (byte R1, byte G1, byte B1, byte R2,
-
- byte G2, byte B2, byte inicio, int numtonos)
-
- {
-
- int deltaR, deltaG, deltaB;
-
- int cont, sent = 1;
-
- int n=abs(numtonos);
-
- byte col=0;
-
- rgb c;
-
- if (n==0) return;
-
- deltaR=R2-R1;
-
- deltaG=G2-G1;
-
- deltaB=B2-B1;
-
- if (numtonos<0) sent=-1;
-
- for (col=ini, cont=0, cont<=n; cont++, col+=sent)
-
- {
-
- c.r =R1+(deltaR*cont/n);
-
- c.g =G1+(deltaR*cont/n);
-
- c.b =B1+(deltaR*cont/n);
-
- set_rgb(c.r, c.g, c.b, col);
-
- }
-
- }
-
- Fernando Moyano
-
- Pamplona
-
-
- CAMBIO DE LETRAS
-
- Las siguientes rutinas han de ser llamadas desde otra funci≤n, y
- permiten convertir los caracteres normales en cursivas, negritas y
- subrayadas. Es tarea fßcil partir de estas rutinas para crear otras
- que hagan cualquier otra cosa, y es algo que puede ser ·til para
- usarlo en alg·n programa, dßndole un toque de distici≤n.
-
- #include <dos.h>
-
- #include <conio.h>
-
- #include <stdio.h>
-
- typedef unsigned int word;
-
- typedef unsigned char byte;
-
- byte far* LoadFont()
-
- /*Esta rutina usa las fuentes de 16 bytes*/
-
- {
-
- word wSegment,wOffset;
-
- asm{
-
- mov di,bp
-
- mov ah,0x11
-
- mov al,0x30
-
- mov bh,6
-
- int 0x10
-
- push es
-
- push bp
-
- mov bp,di
-
- pop ax
-
- mov wOffset,ax
-
- pop ax
-
- mov wSegment,ax
-
- }
-
- return (byte far*)MK_FP(wSegment,wOffset);
-
- }
-
- void SetFont(byte far *pby)
-
- /*Esta rutina usa las fuentes de 16 bytes*/
-
- {
-
- asm{
-
- push bp
-
- mov ah,0x11
-
- mov al,0
-
- mov bh,16 /*16bytes por carßcter*/
-
- mov bl,0
-
- mov cx,97 /*97 caracteres*/
-
- mov dl,'!' /*carßcter a partir del cual comienzo*/
-
- mov dh,0
-
- les bp,pby
-
- int 0x10
-
- pop bp
-
- }
-
- }
-
- void Bold()
-
- /*Esta rutina usa las fuentes de 16 bytes*/
-
- {
-
- byte far *pbyOld,pbyNew[16*97];
-
- int i;
-
- pbyOld=LoadFont();
-
- for(i=0;i<16*97;i++)
-
- pbyNew[i]=(pbyOld[i+16*33]>>1)|pbyOld[i+16*33];
-
- SetFont(pbyNew);
-
- }
-
- void Underlined()
-
- /*Esta rutina usa las fuentes de 16 bytes*/
-
- {
-
- byte far *pbyOld,pbyNew[16*97];
-
- int i;
-
- pbyOld=LoadFont();
-
- for(i=0;i<16*97;i++)
-
- if(i%16==15)
-
- pbyNew[i]=0xFF;
-
- else
-
- pbyNew[i]=pbyOld[i+16*33];
-
-
- SetFont(pbyNew);
-
- }
-
- void Cursive()
-
- /*Esta rutina usa las fuentes de 16 bytes*/
-
- {
-
- byte far *pbyOld,pbyNew[16*97];
-
- int i;
-
- pbyOld=LoadFont();
-
- for(i=0;i<16*97;i++)
-
- switch(i%16)
-
- {
-
- case 2:
-
- case 3:
-
- pbyNew[i]=pbyOld[i+16*33]>>2;
-
- break;
-
- case 4:
-
- case 5:
-
- pbyNew[i]=pbyOld[i+16*33]>>1;
-
- break;
-
- case 10:
-
- case 11:
-
- pbyNew[i]=pbyOld[i+16*33]<<1;
-
- break;
-
- case 12:
-
- case 13:
-
- pbyNew[i]=pbyOld[i+16*33]<<2;
-
- break;
-
- default:
-
- pbyNew[i]=pbyOld[i+16*33];
-
- }
-
- SetFont(pbyNew);
-
- }
-
- Daniel PΘrez Palomar
-
- Barcelona
-
-
-
- CONTROL DE LA IMPRESORA
-
- Esta rutina sirve para programas que deseen conocer el estado de la
- impresora antes de mandar algo a imprimir, y en el caso de que no estΘ
- correctamente conectada puedan mandar el c≤digo de error
- correspondiente.
-
- El programa estß realizado en Borland C++ 2.0, y hace uso de la
- funci≤n ½biosprint╗ de la librerφa ½bios.h╗.
-
- Estß funci≤n act·a bajo los registros de la BIOS y nos permitirß saber
- si nuestra impresora estß ocupada, tiene alg·n error en el dispositivo
- de entrada/salida, si tiene papel, etc.
-
- La funci≤n ½biosprint╗ trabaja devolviendo un valor que se guardarß en
- este caso en la variable ½printer╗. Seg·n el valor que reciba
- sabremos su estado. Otra utilidad de esta funci≤n es la de
- reinicializar la impresora una vez ya conectada. Esto puede resultar
- de gran utilidad, si se desean eliminar los datos del buffer de la
- impresora cuando se estß realizando un programa. Se hace cambiando el
- valor ½estado╗ por 1, de tal modo que la impresora se reiniciarß.
-
- #include <conio.h>
-
- #include <bios.h>
-
- #include <stdio.h>
-
- #define ESTADO 2
-
- #define PUERTO 0
-
- int printer;
-
- main ()
-
- {
-
- clrscr ();
-
- textcolor(cyan + blynk);
-
- cprintf ("\n ......... ESTADO DE LA IMPRESORA ..........");
-
- printer = biosprint (ESTADO, 0, PUERTO);
-
- /* La variable printer almacena el estado de la impresora */
-
- if (printer & 0x10) printf ("\n\nImpresora conectada...");
-
-
- else
-
- printf("\n\nLa impresora no estß conectada...");
-
- if (printer & 0x08) printf("\nError en el dispositivo I/O...");
-
- else
-
- printf("\nNo hay error en el dispositivo I/O...");
-
- if (printer & 0x01) printf (\nPaso del tiempo adjudicado...");
-
- else
-
- printf("\nNO - paso del tiempo adjudicado...");
-
- if (printer & 0x20) printf ("\nLa impresora no encuentra el papel...");
-
- else
-
- printf("\nLa impresora tiene papel...");
-
- if (printer & 0x40) printf ("\nSI - Acuse de recibo...");
-
- else
-
- printf(\nNO - Acuse de recibo...");
-
- if (printer & 0x80) printf("\nImpresora no ocupada...");
-
- else
-
- printf("\nImpresora ocupada...");
-
- getch();
-
- exit(1);
-
- }
-
- Lluφs Company Ordo±o
-
- Terrassa (Barcelona)
-
-
- ELEGIR EL DIRECTORIO
-
- Todos nos hemos sentido tentados en alguna ocasi≤n a escribir alg·n
- peque±o programa que nos facilitase las tareas de movernos por nuestro
- disco duro. Pero el principal inconveniente con el que topßbamos era
- que un cambio en el ßrbol de directorios del mismo nos obligaba a
- reescribir o recompilar la utilidad creada.
-
- La siguiente rutina nos ofrece una interesante alternativa. En
- efecto, el programa ½Eligdir╗ nos permite situarnos en cualquier
- subdirectorio de la unidad por defecto, con tan s≤lo algunas
- pulsaciones de teclas de funci≤n. Ocupa apenas 11 Kbytes y tan s≤lo
- lee los 10 primeros subdirectorios de cada nivel (lo que puede ser
- tanto una ventaja como un inconveniente).
-
- Su algoritmo de funcionamiento es el siguiente. En primer lugar lee
- las entradas en el directorio actual, almacenando en una cola los
- directorios encontrados. A continuaci≤n se pide por teclado la
- pulsaci≤n de una tecla de funci≤n y se salta al directorio asociado a
- la misma leyendo la cola anterior. El proceso se repite hasta que la
- entrada por teclado sea distinta de cualquiera de las teclas de
- funci≤n.
-
- A±adir por ·ltimo que este programa fue escrito para el compilador
- Turbo C 2.0 de Borland, siendo recomendable su compilaci≤n en los
- modelos tiny o small.
-
- #include <dir.h>
-
- #include <stdio.h>
-
- #include <stdlib.h>
-
- #include <dos.h>
-
- #include <bios.h>
-
- char todos[]="*.*";
-
- /*patr≤n de b·squeda*/
-
- struct ffblk f;
-
- /*file control block*/
-
- int atributos=FA_DIREC;
-
- /*atributo de fichero=directorio*/
-
- int ret;
-
- /*resultado de funciones findfirst y findnext*/
-
- char diract[MAXDIR];
-
- /*cadena con el nombre del camino actual*/
-
- extern unsigned _stacklen=512;
-
- /*tama±o de pila y heap (mφnimo)*/
-
- extern unsigned _heaplen=1024;
-
- struct cola
-
- /*cola de los directorios seleccionados*/
-
- {char nombre[13];
-
- struct cola *sig;
-
- } *pcab,*pcola;
-
- /*punteros a cabeza y fin de la cola*/
-
- void IniciaC()
-
- /*Inicia la cola, borrßndola*/
-
- { struct cola *p1,*p2;
-
- if (pcab!=NULL)
-
- {p1=pcab;p2=pcab->sig;
-
- while(p2!=NULL)
-
- {free(p1);
-
- p1=p2;
-
- p2=p2->sig;
-
- }
-
- free(p1);
-
- pcab=NULL;
-
- }
-
- }
-
- void MeterC(cad)
-
- /*Mete un string en la cola*/
-
- char cad[13];
-
- {struct cola *p2;
-
- if ((p2=malloc(sizeof(*p2)))==NULL)
-
- {puts("No hay memoria suficiente");exit(0);}
-
- strcpy(p2->nombre,cad);
-
- p2->sig=NULL;
-
- if (pcab==NULL) pcab=p2;
-
- else pcola->sig=p2;
-
- pcola=p2;
-
- }
-
- EsvaciaC()
-
- /*Comprueba si la cola estß vacφa*/
-
- {return(pcab==NULL);}
-
- void BuscaDIR()
-
- /*Busca los directorios y los mete en la cola*/
-
- {short c=0;
-
- IniciaC();
-
- ret=findfirst(todos,&f,atributos);
-
- /*busca el primero*/
-
- if (ret==-1) return;
-
- /*si no estß, salir*/
-
- if (f.ff_attrib==FA_DIREC && (f.ff_name[0]!='.'))
-
- /*si es directorio vßlido*/
-
- {MeterC(f.ff_name);c++;}
-
- /*meterlo en cola*/
-
- for(;;)
-
- {ret=findnext(&f);
-
- /*busca el siguiente*/
-
- if ((ret==-1) || (c>10)) break;
-
- /*si no encontrado o hay mßs de 10, salir*/
-
- if (f.ff_attrib==FA_DIREC) {MeterC(f.ff_name);c++;}
-
- }
-
- if (EsvaciaC()) {puts("No encontrΘ directorios");exit(0);}
-
- }
-
- void Eligeopcion()
-
- /*Muestra los directorios seleccionados y pide uno de ellos*/
-
- {struct cola *p;
-
- int c,d;
-
- int tecla;
-
- getcurdir(0,diract);
-
- /*escribe directorio actual*/
-
- printf ("\n\n DIRECTORIO ACTUAL : \\%s",diract);
-
- puts ("\n Elige directorio: ");
-
- for(p=pcab,c=1;p!=NULL && c<=10;p=p->sig,c++)
-
- printf ("\n F%d - %s",c,p->nombre);
-
- puts ("\n OTRA CUALQUIERA - fin");
-
- tecla=bioskey(0)>>8;
-
- /*obtiene c≤digo tecla pulsada*/
-
- if ((tecla<0x3b)||(tecla>0x44)) exit(0);
-
- /*si no es tecla funci≤n, salir*/
-
- tecla-=0x3b;
-
- for(p=pcab,d=0;(tecla>d) && (p!=NULL);p=p->sig,d++);
-
- /*ir a dir seleccionado*/
-
- chdir(p->nombre);
-
- }
-
- main() /*Rutina principal*/
-
- {BuscaDIR();
-
- while(!EsvaciaC())
-
- {Eligeopcion();
-
- BuscaDIR();
-
- }
-
- }
-
- Gonzalo Le≤n Manzano
-
- Albacete
-
-
- EFECTO DE SOMBREADO
-
- Con esta funci≤n en C podemos dotar a nuestros programas de ventanas y
- men·s con sombra. Las cajas son sencillas de hacer con las funciones
- y procedimientos incluidos en C, pero la dificultad surge al crear las
- sombras. Esta funci≤n nos ayudarß durante el proceso de sombreado.
-
- El truco estß en leer los caracteres adecuados de la pantalla y
- cambiarles el atributo que llevan asociado, es decir, el color de
- primer plano y el de fondo. El nuevo atributo ha de ser gris sobre
- negro.
-
- La siguiente funci≤n se usa para crear el efecto descrito alrededor de
- una regi≤n rectangular de coordenadas (x1,y1) (x2,y2).
-
- // Esta funci≤n dibuja una "sombra" en funci≤n de las coordenadas
- dadas
-
- // Se supone que se habrß dibujado una caja con esas mismas
- coordenadas
-
- // Para hacer la sombra se cambia el atributo de los caracteres
- adecuados
-
- // a gris sobre negro
-
- void Shadow(int x1,int y1,int x2,int y2)
-
- {
-
- int j=0;
-
- char ch;
-
- union REGS r;
-
- // Se dibuja el lado inferior de la sombra
-
- for(j=x1+2;j<x2+3;j++)
-
- {
-
- gotoxy(j,y2+1); // coloco el cursor en la posici≤n adecuada
-
- r.h.ah=0x08;
-
- r.h.bh=0x00;
-
- int86(0x10,&r,&r); // consigo el carßcter de esa posici≤n
-
- ch=r.h.al; // ch contiene el carßcter
-
- textattr(7); // cambio el atributo del carßcter
-
- putch(ch); // y lo pongo de nuevo
-
- }
-
- //-- se dibuja el lado derecho de la sombra --
-
- for(j=y1+1;j<y2+1;j++)
-
- {
-
- gotoxy(x2+1,j); // coloco el cursor en la posici≤n adecuada
-
- r.h.ah=0x08;
-
- r.h.bh=0x00;
-
- int86(0x10,&r,&r); // consigo el carßcter de esa posici≤n
-
- ch=r.h.al; // ch contiene el carßcter
-
- textattr(7); // cambio el atributo del carßcter
-
- putch(ch); // y lo pongo de nuevo
-
- }
-
- for(j=y1+1;j<y2+1;j++)
-
- {
-
- gotoxy(x2+2,j); // coloco el cursor en posici≤n
-
- r.h.ah=0x08;
-
- r.h.bh=0x00;
-
- int86(0x10,&r,&r); // consigo el carßcter adecuado
-
- ch=r.h.al; // ch contiene el carßcter
-
- textattr(7); // cambio el atributo del carßcter
-
- putch(ch); // y lo vuelvo a colocar en su sitio
-
- }
-
- }
-
- Daniel Sßnchez Teodoro
-
- Granada
-
-
- DESARROLLA TUS PROPIOS ESTEREOGRAMAS
-
- Con esta rutina podemos realizar estereogramas de una sola imagen.
- Los estereogramas son esas extra±as imßgenes (tan de moda hoy en dφa)
- que ½esconden╗ objetos en tres dimensiones, pero que pueden verse
- empleando una determinada tΘcnica. Demetrio Fernßndez nos ha mandado
- una rutina creada por Θl mismo que permite, a partir de una imagen,
- desarrollar un estereograma. Estß escrita en C y sorprende por su
- peque±o tama±o, pues tan s≤lo ocupa menos de 60 lφneas.
-
- Para sacar provecho de todas sus prestaciones basta con crear el
- dibujo o imagen, ponerla en pantalla y luego llamar al procedimiento
- ½pantalla╗.
-
- unsigned rep=40;
-
- // ancho de repetici≤n
-
- unsigned aleatorio[200];
-
- // patr≤n con el que trabaja el programa
-
- unsigned aleatorio2[200];
-
- // patr≤n original
-
- unsigned maximo=40;
-
- //igual que rep pero este es temporal
-
- unsigned NPUNTOS=1;
-
- //el n·mero de puntos que se saltan
-
- unsigned paralelo=1;
-
- // modo de visualizaci≤n en paralelo o cruzado
-
- // hace un simple negativo de la imagen
-
- void genera(unsigned ini,unsigned fin)
-
- // cuando hay que aumentar el aleatorio
-
- // mete trozos del aleatorio2
-
- {
-
- int i,j,d;
-
- d=fin-ini;
-
- j=random(rep-d);
-
- for(i=ini;i<fin;i++)
-
- {aleatorio[i]=aleatorio2[j+i-ini];}
-
- }
-
- void genera2(unsigned *tabl,unsigned ini,unsigned fin)
-
- // aquφ genera puntos aleatorios pero
-
- // podΘis poner lo que querßis como patron
-
- {
-
- int i;
-
- for(i=ini;i<fin;i++)
-
- {tabl[i]=random(getmaxcolor());}
-
- }
-
- void adelante(unsigned ini,unsigned salto)
-
- // incrementamos profundidad en la imagen
-
-
- {
-
- unsigned i;
-
- for (i=maximo;i>ini;i--) aleatorio[i+NPUNTOS*salto]=aleatorio[i];
-
- maximo+=NPUNTOS*salto;
-
- genera(i,i+NPUNTOS*salto);
-
- }
-
- void atras(unsigned ini,unsigned salto)
-
- // decrementamos profundidad en la imagen
-
- {
-
- unsigned i;
-
- for (i=ini;i<maximo;i++) aleatorio[i]=aleatorio[i+NPUNTOS*salto];
-
- maximo-=NPUNTOS*salto;
-
- }
-
- void rastrealinea(unsigned numlin)
-
- // genera cada lφnea
-
- {
-
- unsigned i,j,k;
-
- unsigned color;
-
- color=0;
-
- maximo=rep;
-
- genera2(aleatorio,numlin,0,maximo*2);
-
- genera2(aleatorio2,numlin,0,maximo*2);
-
- j=0;
-
- for(i=0;i<getmaxx();i++)
-
- {if (paralelo) k=15-getpixel(i,numlin);
-
- else k=getpixel(i,numlin);
-
- if (k!=color)
-
- {if (k<color) adelante(j,color-k);
-
- else atras(j,k-color);
-
- color=k;}
-
- putpixel(i,numlin,aleatorio[j]);
-
- j=(j+1)%maximo;}
-
- }
-
- void pantalla(void)
-
- // hace un estereograma de toda la pantalla
-
- {
-
- unsigned i;
-
- for (i=0;i<=getmaxy();i++)
-
- {
-
- if (i%2) rastrealinea(i);
-
- else rastrealinea(480-i);}
-
- }
-
- Nota sobre la visualizaci≤n: Christopher W. Tyler fue el creador de
- los estereogramas de una sola imagen. Este tipo de estereogramas no
- son en verdad una sola imagen, sino siete u ocho imßgenes iguales
- puestas unas juntas con las otras hasta formar una ·nica imagen y el
- efecto de profundidad. La tΘcnica de visualizaci≤n consiste en poner
- el punto focal detras de la pßgina que estamos viendo, tratando de
- situar la vista mßs allß de la hoja. Se consigue acercando la imagen
- (en este caso la pantalla) a los ojos y despuΘs separßndola (en este
- caso la cabeza) hasta que veamos las tres dimensiones.
-
- Demetrio Fernßndez Alvarez
-
- Oviedo
-
-
- TRATAMIENTO DE IMAGENES
-
- Las siguientes rutinas son dos procedimientos que nos van a permitir,
- en primer lugar, capturar cualquier imagen que se pueda sacar por
- pantalla (incluso aquellas de 256 colores), para convertirla en un
- formato reconocible por la segunda rutina, que serß la que dibujarß
- esa misma imagen pero adaptßndola a un polφgono que le pasaremos como
- parßmetro.
-
- Para utilizar estas rutinas en los nuevos programas hay que incluir el
- fichero ½trans_ima.h╗, ademßs de indicar a nuestro compilador que debe
- enlazar nuestro programa y el fichero ½trans_ima.c╗.
-
- El programa ½Trans_ima.h╗ es el siguiente:
-
- /* TRANSFORMA IMAGEN
-
- Este conjunto de rutinas estß pensado para capturar imßgenes y luego
- adaptarlas a cualquier polφgono, sea o no rectangular.
-
- - captura: Coge una zona de la pantalla grßfica y la captura en el
- formato t_imagen.
-
- - D_dibuja: Adapta la imagen que se le pasa como parßmetro al
- polφgono que le indicamos en la variable de tipo t_puntos.
-
- El tipo t_puntos no es mßs que un registro con cuatro puntos que
- se±alan los vΘrtices de un polφgono.
-
- */
-
- struct t_imagen
-
- {unsigned tam_max_x,tam_max_y;
-
- unsigned char huge *ptr;
-
- };
-
- struct t_punto
-
- {int x,y;};
-
- struct t_puntos
-
- {struct t_punto p1,p2,p3,p4;};
-
- void D_dibuja (struct t_imagen,struct t_puntos);
-
- struct t_imagen captura (int,int,int,int);
-
-
- El programa ½Trans_ima.c╗ es el siguiente:
-
- #include "alloc.h"
-
- #include "graphics.h"
-
- #include "math.h"
-
- #include "trans_ima.h"
-
- struct t_coef
-
- {float x,y;};
-
- struct t_coefs
-
- {struct t_coef c1,c2,c3,c4;};
-
- void calcula_coef (struct t_puntos,struct t_coefs *);
-
- void calcula_incremento_a (struct t_puntos,float *);
-
- void calcula_incremento_b (struct t_puntos puntos,float *incb);
-
- struct t_punto S_destino (float,float,struct t_coefs);
-
- struct t_punto S_origen (struct t_imagen,float,float);
-
- int color_origen (struct t_imagen,struct t_punto);
-
- struct t_imagen captura (int x1,int y1,int x2,int y2)
-
- {unsigned i,j;
-
- struct t_imagen imagen;
-
- unsigned seg;
-
- int error;
-
- imagen.ptr = farmalloc ((unsigned long) (y2-y1+1)*(x2-x1+1));
-
- if (imagen.ptr != NULL)
-
- {imagen.tam_max_x = x2-x1;
-
- imagen.tam_max_y = y2-y1;
-
- for (i=0;i<=y2-y1;i++)
-
- {for (j=0;j<=x2-x1;j++)
-
- {imagen.ptr [(unsigned long) i*(x2-x1+1)+j] = getpixel (x1+j,y1+i);}
-
- }
-
- }
-
- return (imagen);
-
- }
-
- void calcula_coef (struct t_puntos puntos,struct t_coefs *coef)
-
- {
-
- coef->c1.x = puntos.p1.x-puntos.p2.x+puntos.p3.x-puntos.p4.x;
-
- coef->c1.y = puntos.p1.y-puntos.p2.y+puntos.p3.y-puntos.p4.y;
-
- coef->c2.x = puntos.p4.x-puntos.p3.x;
-
- coef->c2.y = puntos.p4.y-puntos.p3.y;
-
- coef->c3.x = puntos.p2.x-puntos.p3.x;
-
- coef->c3.y = puntos.p2.y-puntos.p3.y;
-
- coef->c4.x = puntos.p3.x;
-
- coef->c4.y = puntos.p3.y;
-
- }
-
- struct t_punto S_destino (float alfa,float beta,struct t_coefs coef)
-
- {struct t_punto p;
-
- p.x = (int) (alfa*beta*coef.c1.x + alfa*coef.c2.x + beta*coef.c3.x +
- coef.c4.x);
-
- p.y = (int) (alfa*beta*coef.c1.y + alfa*coef.c2.y + beta*coef.c3.y +
- coef.c4.y);
-
- return (p);
-
- }
-
- struct t_punto S_origen (struct t_imagen imagen,float alfa,float beta)
-
- {struct t_punto p;
-
- p.x = imagen.tam_max_x -(int) (beta*imagen.tam_max_x);
-
- p.y = imagen.tam_max_y -(int) (alfa*imagen.tam_max_y);
-
- return (p);
-
- }
-
- int color_origen (struct t_imagen imagen,
-
- struct t_punto p)
-
- {
-
- return (imagen.ptr [(unsigned long) p.y*(imagen.tam_max_x+1)+p.x]);
-
- }
-
- void calcula_incremento_a (struct t_puntos puntos,float *inca)
-
- {unsigned dist1,dist2;
-
- float dist;
-
- int vx,vy;
-
- vx = abs (puntos.p2.x-puntos.p1.x);
-
- vy = abs (puntos.p2.y-puntos.p1.y);
-
- dist1 = ((vx > vy) ? vx : vy);
-
- vx = abs (puntos.p3.x-puntos.p4.x);
-
- vy = abs (puntos.p3.y-puntos.p4.y);
-
- dist2 = ((vx > vy) ? vx : vy);
-
- dist = (((dist1) > (dist2)) ? (dist1) : (dist2));
-
- *inca = 1/(dist+1);
-
- }
-
- void calcula_incremento_b (struct t_puntos puntos,float *incb)
-
- {unsigned dist1,dist2;
-
- float dist;
-
- int vx,vy;
-
- vx = abs (puntos.p4.x-puntos.p1.x);
-
- vy = abs (puntos.p4.y-puntos.p1.y);
-
- dist1 = ((vx > vy) ? vx : vy);
-
- vx = abs (puntos.p2.x-puntos.p3.x);
-
- vy = abs (puntos.p2.y-puntos.p3.y);
-
- dist2 = ((vx > vy) ? vx : vy);
-
- dist = (((dist1) > (dist2)) ? (dist1) : (dist2));
-
- *incb = 1/(dist+1);
-
- }
-
- void D_dibuja (struct t_imagen origen,
-
- struct t_puntos puntos)
-
- {float alfa,beta;
-
- struct t_punto p;
-
- struct t_coefs coef;
-
- int color;
-
- float inca,incb;
-
- calcula_incremento_a (puntos,&inca);
-
- calcula_incremento_b (puntos,&incb);
-
- calcula_coef (puntos,&coef);
-
- for (alfa=0;alfa<=1;alfa+=inca)
-
- for (beta=0;beta<=1;beta+=incb)
-
- {p = S_origen (origen,alfa,beta);
-
- color = color_origen (origen,p);
-
- p = S_destino (alfa,beta,coef);
-
- putpixel (p.x,p.y,color);
-
- }
-
- }
-
- Siguiendo estos pasos, tenemos a nuestra disposici≤n dos rutinas:
-
- - struct t_imagen captura(int x1, int y1, int x2, int y2)
-
- - void D_dibuja (struct t_imagen imagen, struct t_puntos p)
-
- La primera funci≤n captura el mapa de bits comprendido entre los
- puntos (x1,y1) y (x2,y2), devolviendo un registro de tipo t_imagen, en
- el que queda almacenada.
-
- El segundo procedimiento coge la imagen previamente capturada y la
- dibuja adaptßndola al polφgono de cuatro vΘrtices indicado por la
- variable p.
-
- Hemos de tener en cuenta que la imagen capturada se almacena en
- memoria principal como una matriz de char, con un byte por cada
- pixel que capturemos. Por lo que si los bitmaps van a ser muy
- grandes tendremos que compilar el programa en modelos como ½Compact╗.
-
- En el siguiente programa vemos un ejemplo de la utilizaci≤n de estas
- rutinas:
-
- #include "alloc.h"
-
- #include "graphics.h"
-
- #include "stdio.h"
-
- #include "fcntl.h"
-
- #include "io.h"
-
- #include "trans_ima.h"
-
- struct t_imagen carga_origen (char *);
-
- int inicia_graficos ();
-
- int main ()
-
- {struct t_puntos puntos;
-
- struct t_imagen origen;
-
- char *cadena = "PC-ACTUAL";
-
- char *aux = " \0";
-
- int i;
-
- inicia_graficos ();
-
- /* PRIMERO SIMPLEMENTE DIBUJAMOS UNA IMAGEN EN LA PANTALLA */
-
- settextstyle (DEFAULT_FONT,HORIZ_DIR,3);
-
- moveto (0,0);
-
- for (i=0;i < strlen (cadena);i++)
-
- {setcolor (i+1);
-
- strnset (aux,cadena [i],1);
-
- outtext (aux);
-
- }
-
- setcolor (i+1);
-
- line (0,textheight (cadena),textwidth (cadena),textheight (cadena));
-
- /* CAPTURAMOS LA PARTE DE LA PANTALLA QUE NOS INTERESA EN UNA VARIABLE
- DE TIPO ORIGEN */
-
- origen.tam_max_x = textwidth (cadena);
-
- origen.tam_max_y = textheight (cadena);
-
- origen = captura (0,0,origen.tam_max_x,origen.tam_max_y);
-
- settextstyle (DEFAULT_FONT,HORIZ_DIR,1);
-
- setcolor (WHITE);
-
- outtextxy (0,getmaxy ()-textheight ("P"),
-
- "Pulsa una tecla para ver la imagen transformada...");
-
- getch ();
-
- if (origen.ptr != NULL) /* ┐HA HABIDO ERROR EN ASIGNACION DE MEMORIA? */
-
- {cleardevice ();
-
- /* DIBUJAMOS LA IMAGEN TRANSFORMADA */
-
- puntos.p1.x = 0;puntos.p1.y = 0;
-
- puntos.p2.x = 0;puntos.p2.y = getmaxy ();
-
- puntos.p3.x = getmaxx ()/2-50;puntos.p3.y = getmaxy ()/2+40;
-
- puntos.p4.x = getmaxx ()/2-50;puntos.p4.y = getmaxy ()/2-40;
-
- D_dibuja (origen,puntos);
-
- puntos.p1.x = getmaxx ()/2-40;puntos.p1.y = getmaxy ()/2+50;
-
- puntos.p2.x = 0;puntos.p2.y = getmaxy ();
-
- puntos.p3.x = getmaxx ();puntos.p3.y = getmaxy ();
-
- puntos.p4.x = getmaxx () /2+40;puntos.p4.y = getmaxy ()/2+50;
-
- D_dibuja (origen,puntos);
-
- puntos.p3.x = getmaxx ()/2+50;puntos.p3.y = getmaxy ()/2+40;
-
- puntos.p2.x = getmaxx ();puntos.p2.y = getmaxy ();
-
- puntos.p1.x = getmaxx ();puntos.p1.y = 0;
-
- puntos.p4.x = getmaxx ()/2+50;puntos.p4.y = getmaxy ()/2-40;
-
- D_dibuja (origen,puntos);
-
- puntos.p2.x = 0;puntos.p2.y = 0;
-
- puntos.p1.x = getmaxx ()/2-40;puntos.p1.y = getmaxy ()/2-50;
-
- puntos.p4.x = getmaxx ()/2+40;puntos.p4.y = getmaxy ()/2-50;
-
- puntos.p3.x = getmaxx ();puntos.p3.y = 0;
-
- D_dibuja (origen,puntos);
-
- free ((void *) origen.ptr);
-
- getch ();
-
- }
-
- else {closegraph ();
-
- printf ("\nError en asignacion de memoria\n");
-
- exit (1);
-
- }
-
- closegraph ();
-
- return (0);
-
- }
-
- int inicia_graficos ()
-
- {int driver,modo,errorcode;
-
- driver = DETECT;
-
- initgraph (&driver,&modo,"");
-
- errorcode = graphresult();
-
- if (errorcode != grOk)
-
- {
-
- printf("Error en graficos: %s\n", grapherrormsg(errorcode));
-
- printf("Pulsa una tecla para terminar.");
-
- getch();
-
- exit(1);
-
- }
-
- return (graphresult ());
-
- }
-
-
- Marcial Martφnez L≤pez
-
- Valencia
-
-
-
-
-
-